package com.backend.demo1.middlewares;

import com.backend.demo1.global.GlobalLog;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import io.micrometer.common.lang.Nullable;
import org.springframework.lang.NonNull;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@Component
public class LoggingMiddleware implements HandlerInterceptor {

    // 请求开始时间
    private static final String START_TIME_ATTRIBUTE = "requestStartTime";

    @Override
    public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) {
        // 记录请求开始时间
        request.setAttribute(START_TIME_ATTRIBUTE, System.currentTimeMillis());
        return true;
    }

    @Override
    public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
                           @NonNull Object handler, @Nullable ModelAndView modelAndView) {
        long startTime = (Long) request.getAttribute(START_TIME_ATTRIBUTE);
        long latency = System.currentTimeMillis() - startTime;
        int status = response.getStatus();
        String latencyStr = latency + "ms";
        String method = request.getMethod();
        String path = request.getRequestURI();
        String clientIP = getClientIP(request);
        String userAgent = request.getHeader("User-Agent");
        String referer = request.getHeader("Referer");
        String query = request.getQueryString();

        // 输出结构化日志
        GlobalLog.info("method={}, path={}, status={}, latency={}, client_ip={}, user_agent={}, referer={}, query={}",
                method, path, status, latencyStr, clientIP, userAgent, referer, query);
    }

    // 获取客户端真实 IP（考虑代理）
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}